#include<dos.h>

#ifdef __cplusplus
    #define __CPPARGS ...
#else
    #define __CPPARGS
#endif

#include<setjmp.h>


void set_g_mode(char mode)
{
asm mov ah,0
asm mov al,mode;
asm int 0x10;
}

void set_vbe_mode(int mode)
{
asm mov ax,0x4f02;
asm mov bx,mode;
asm int 0x10
}

void putc(char c)
{
if(c!=0)
{
asm mov ah,0x0e;
asm mov al,c;
asm int 0x10;
}
}

void print(char *buffer)
{
char c;
asm mov si,buffer
while(c!=0)
{
asm lodsb;
asm mov c,al;
putc(c);
}
}

char get_kbd_buffer()
{
char c;
asm mov ah,1;
asm mov al,1;
asm int 0x16;
asm mov c,al;
return c;
}

char getkey()
{
char c;
c=get_kbd_buffer();
if(c!=0)
{
asm mov ax,0;
asm int 0x16;
}
return c;
}

char idle()
{
char c;
do
c=getkey();
while(c==0);
return c;
}

int task1();
int task2();

int task_id=0;

void interrupt clock(__CPPARGS)
{
 putc(task_id+0x30);
 if(task_id==0)
 {
  if(task2_run==0)
  {
   task_id=1;
   task2();
  }
  else
  {
   task_id=1
   longjmp(tss2,1);
  }
 else
 {
  task_id=0;
  longjmp(tss1,1);
 }
}

jmp_buf tss1,tss2;

int task1()
{
char *task="Task1...";
print(task);
idk:
setjmp(tss1);
goto idk;
return 0;
}

int task2_run=0;

int task2()
{
char *task="Task2...";
print(task);
task2_run=1;
idk:
setjmp(tss2);
goto idk;
return 0;
}

int main()
{
int task1_ret;
set_g_mode(3);
char *initmsg="Press any key to start FU8086... ";
print(initmsg);
idle();
setvect(0x1c,clock);
task1_ret=task1();
return 0;
}